package cn.tedu.csmall.stock.webapi.controller;

import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall.commons.restful.JsonResult;
import cn.tedu.csmall.commons.restful.ResponseCode;
import cn.tedu.csmall.stock.service.IStockService;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/base/stock")
@Api(tags = "库存管理模块")
public class StockController {
    @Autowired
    IStockService stockService;

    @PostMapping("/reduce/count")
    @ApiOperation("减少库存数量的方法")
    //fallback属性是设置在当前方法正常运行期间出现异常时会运行的自定义降级方法
    @SentinelResource(value = "减少库存数量的方法",
            blockHandler = "blockError",
            fallback = "fallbackError"
    )
    public JsonResult reduceCount(StockReduceCountDTO stockReduceCountDTO){
        stockService.updateStockCount(stockReduceCountDTO);
//        try {
//            Thread.sleep(5000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return JsonResult.ok("库存减少成功！");
    }

    //Sentinel自定义限流方法规则
    //1.访问修饰符必须是public
    //2.返回值类型必须和被限流的控制器方法一致,.如上面被限流的方法返回值是JsonResult此方法就业要是JsonResult
    //3.方法名必须和@SentinelResurce的blockHandler属性设置的一样
    //4.参数列表也需要和被限流的方法一致,在末尾额外添加BlockException类型的异常
    public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO, BlockException e){
        //这个方法会在请求被限流时执行，返回值应包含相应的提示信息
        return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR,"服务器忙，请稍后再试!");
    }

    //自定义降级方法的格式与上面的限流方法基本一致，
    //参数列表添加的异常类型为Throwable异常
    public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO,
                                    Throwable e){
        //显示错误信息
        e.printStackTrace();
        //返回异常的错误信息
        return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR,
                "方法运行期间出现问题，执行了降级方法"+e.getMessage());
    }
}
